package com.umessage.hotel.service.impl;


import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.umessage.common.service.RedisService;
import com.umessage.common.service.impl.BaseService;
import com.umessage.common.util.QRCodeUtil;
import com.umessage.hotel.dao.RoomInfoMapper;
import com.umessage.hotel.domain.MemberDiscount;
import com.umessage.hotel.domain.MemberInfo;
import com.umessage.hotel.domain.PictureInfo;
import com.umessage.hotel.domain.RoomInfo;
import com.umessage.hotel.domain.RoomStatus;
import com.umessage.hotel.model.PictureModel;
import com.umessage.hotel.model.RoomModel;
import com.umessage.hotel.service.MemberDiscountService;
import com.umessage.hotel.service.MemberInfoService;
import com.umessage.hotel.service.PictureInfoService;
import com.umessage.hotel.service.RoomInfoService;
import com.umessage.hotel.service.RoomStatusService;
import com.umessage.system.domain.Dict;
import com.umessage.system.service.DictService;

import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

@Service("roomInfoService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class RoomInfoServiceImpl extends BaseService<RoomInfo> implements RoomInfoService {
	
	private static final Logger logger = LoggerFactory.getLogger(RoomInfoServiceImpl.class);
	
	@Autowired
	private DictService dictService;
	@Autowired
	private PictureInfoService picService;
	@Autowired
	private RoomStatusService roomStatusService;
	@Autowired
	private RoomInfoMapper roomMapper;
	@Autowired
	private MemberDiscountService memberService;
	@Autowired
	private MemberInfoService memberInfoService;
	@Autowired
	private RedisService redisService;

	@Override
	public List<RoomInfo> findRoomInfoAll(String roomId, String hotelId, String bookable) {
		try {
			Example example = new Example(RoomInfo.class);
			Criteria createCriteria = example.createCriteria();
			if (StringUtils.isNotBlank(hotelId)) {
				createCriteria.andCondition("hotel_id=", hotelId);
			}
			if (StringUtils.isNotBlank(roomId)) {
				createCriteria.andCondition("room_id=", roomId);
			}
			if (StringUtils.isNotBlank(bookable)) {
				createCriteria.andCondition("is_bookable=", bookable);
			}
			example.setOrderByClause("room_id");
			return this.selectByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
			return new ArrayList<>();
		}
	}

	/**
	 * 数据转换
	 * 
	 * @param room
	 * @return
	 */
	public RoomModel convertToRoomModel(RoomInfo room,String type,String roomsType) {
		RoomModel roomModel = new RoomModel();
		String ignoreProperties = "residentLimit";
		BeanUtils.copyProperties(room, roomModel, ignoreProperties);
		roomModel.setRoomId(room.getRoomId().toString());
		Dict dict = new Dict();
		dict.setTableName("t_room_info");
			//设施
			//Map<String, String> facMap = redisService.getMap("facMap");
			//if(facMap == null) {
			Map<String, String> facMap = new HashMap<String, String>();
				if (room.getFacilities() != null) {
					dict.setFieldName("facilities");
					List<Dict> facDicts = this.dictService.findAllDicts(dict);
					String[] strs1 = room.getFacilities().split(",");
					for (Dict fac : facDicts) {
						for (int i = 0; i < strs1.length; i++) {
							if (fac.getKeyy().equals(strs1[i].toString())) {
								facMap.put(fac.getKeyy(), fac.getValuee());
							}
						}
					}
				}
			//	redisService.setMap("facMap", facMap);
			//	redisService.pexpire("facMap", 1000 * 60L * 30);
			//}
			roomModel.setFacilities(facMap);
			//房策
			//if(!"1".equals(roomsType)) {
			//Map<String, String> policies = redisService.getMap("policies");
			//if(policies == null) {
				Map<String, String> policies = new HashMap<String, String>();
				if (room.getPolicies() != null) {
					String[] strs3 = room.getPolicies().split(",");
					dict.setFieldName("policies");
					List<Dict> polsDicts = this.dictService.findAllDicts(dict);
					for (Dict pol : polsDicts) {
						for (int i = 0; i < strs3.length; i++) {
							if (pol.getKeyy().equals(strs3[i].toString())) {
								policies.put(pol.getKeyy(), pol.getValuee());
								//用于判定房间订单是否可取消
								if("不可退款".equals(pol.getValuee())) {
									roomModel.setNotCancle(pol.getValuee());
								}
							}
						}
					}
				}
			//	redisService.setMap("policies", policies);
			//	redisService.pexpire("policies", 1000 * 60L * 30);
			//}
			roomModel.setPolicies(policies);
			//}
		roomModel.setResidentLimit(room.getResidentLimit());
		roomModel.setBookable(room.getIsBookable());
		if(type!=null) {
			PictureInfo pic = new PictureInfo();
			pic.setTableName("t_room_info");
			pic.setTableId(String.valueOf(room.getRoomId()));
			pic.setType(type);
			List<PictureInfo> pics = this.picService.findPictures(pic);
			List<PictureModel> picsModel = new ArrayList<>();
			if (pics != null) {
				for (int i = 0; i < pics.size(); i++) {
					PictureModel picModel = new PictureModel();
					picModel.setPicHref(pics.get(i).getPicHref());
					picModel.setPicUrl(pics.get(i).getPicUrl());
					picModel.setSort(pics.get(i).getSort());
					picsModel.add(picModel);
				}
				roomModel.setRoomPics(picsModel);
			}
		}
		return roomModel;
	}

	@Override
	@Transactional
	public void addRoomInfo(RoomInfo roomInfo) {
		this.roomMapper.saveRoom(roomInfo);
	}
	@Override
	@Transactional
	public void addRoomInfoAndPic(RoomInfo roomInfo) {
		this.addRoomInfo(roomInfo);
		PictureInfo picture = roomInfo.getPicture();
		picture.setAddTime(new Date());
		picture.setAddAcc(roomInfo.getAddAcc()+"");
		picture.setTableId(roomInfo.getRoomId()+"");
		picture.setTableName("t_room_info");
		picture.setType("1");
		this.picService.save(picture);
		PictureInfo[] pictures = roomInfo.getPictures();
		if(pictures!=null) {
			for (PictureInfo pic : pictures) {
				pic.setAddTime(new Date());
				pic.setAddAcc(roomInfo.getAddAcc()+"");
				pic.setTableId(roomInfo.getRoomId()+"");
				pic.setTableName("t_room_info");
				pic.setType("2");
				this.picService.save(pic);
			}
		}
	}

	@Override
	@Transactional
	public void updateRoomInfo(RoomInfo roomInfo) {
		this.updateNotNull(roomInfo);
	}
	/**
	 * 根据roomid返回一段时间内的价格
	 */
	@Override
	public RoomInfo getRoomAvgByRoomId(String roomId,String hotelId,Date beginTime,Date endTime) {
		
		//获取房间原数据
		List<RoomInfo> rooms=this.findRoomInfoAll(roomId, hotelId, null);
		RoomInfo roomInfo = null;
		if(rooms != null && rooms.size() > 0) {
			roomInfo=rooms.get(0);
		}
		return getRoomAvgPrice(hotelId, roomInfo, beginTime, endTime);
	}

	/**
	 * 获取房间平均价格
	 * @param hotelId
	 * @param roomInfo
	 * @param beginTime
	 * @param endTime
	 * @return
	 */
	public RoomInfo getRoomAvgPrice(String hotelId, RoomInfo roomInfo, Date beginTime, Date endTime) {
		//获取天数
		Calendar cale = Calendar.getInstance();
		cale.setTime(beginTime);
		int bMonth = cale.get(Calendar.MONTH )+1;
		int bDay =cale.get(Calendar.DAY_OF_MONTH);
		cale.setTime(endTime);
		int eMonth = cale.get(Calendar.MONTH )+1;
		int eDay =cale.get(Calendar.DAY_OF_MONTH);
		int countDay=0;
		if(bMonth==eMonth) {
			countDay=eDay-bDay;
		}else {
			cale.add(bMonth, 1);
			cale.set(Calendar.DAY_OF_MONTH, 0);
			int day=cale.get(Calendar.DAY_OF_MONTH);
			countDay=day-bDay+eDay;
		}
		if(roomInfo != null) {
			//获取有变化的房态
			Map<String,Object> map=new HashMap<>();
			map.put("hotelId", hotelId);
			map.put("endTime", endTime);
			map.put("beginTime", beginTime);
			map.put("roomId", roomInfo.getRoomId());
			List<RoomStatus> rss=this.roomStatusService.findRoomStatus(map);
			BigDecimal avg = BigDecimal.ZERO;
			BigDecimal sumNotUpdate = BigDecimal.ZERO;
			BigDecimal sumNumUpdate = BigDecimal.ZERO;
			if(!rss.isEmpty()) {
				for (RoomStatus rs : rss) {
					if("0".equals(rs.getIsBook())) {
						roomInfo.setIsBookable("0");
						return roomInfo;
					}
					sumNumUpdate=sumNumUpdate.add(rs.getPrice());
				}
			}
		    sumNotUpdate = roomInfo.getOriginalPrice().multiply(BigDecimal.valueOf(countDay-rss.size()));
		    avg=(sumNumUpdate.add(sumNotUpdate)).divide(BigDecimal.valueOf(countDay),0,BigDecimal.ROUND_UP);
			roomInfo.setOriginalPrice(avg.setScale(2, BigDecimal.ROUND_UP));
		    roomInfo.setCountDay(BigDecimal.valueOf(countDay));
			return roomInfo;
		}
		return null;
	}

	@Override
	public List<RoomModel> listRooms(String hotelId,Date beginTime,Date endTime,String memberId,String roomsType) {
		List<RoomModel> list = new ArrayList<RoomModel>();
		List<RoomInfo> rooms = this.findRoomInfoAll(null, hotelId, null);
		if(!rooms.isEmpty()) {
			Map<String,Object> map=new HashMap<>();
			map.put("hotelId", hotelId);
			map.put("endTime", endTime);
			map.put("beginTime", beginTime);
			for (RoomInfo roomInfo : rooms) {
				List<String> roomIds = roomStatusService.findRoomIdsNotBook(map);
				String roomId = roomInfo.getRoomId()+"";
				boolean isOk = roomIds.contains(roomId);
				if(isOk) {
					roomInfo.setIsBookable("0");
					roomInfo.setDiscountPrice(roomInfo.getOriginalPrice());
				}else {
					roomInfo = this.getRoomAvgPrice(hotelId, roomInfo, beginTime, endTime);
					MemberInfo memberInfo=this.memberInfoService.findMemberById(memberId);
					this.getDisCountPrice(memberInfo,roomInfo);
				}
				RoomModel roomModel = this.convertToRoomModel(roomInfo, "1",roomsType);
				list.add(roomModel);
			}
			return list;
		}
		return null;
	}

	@Override
	public RoomModel loadRoom(String hotelId,String roomId,Date endTime,Date beginTime,String memberId) {
		RoomInfo roomInfo=this.getRoomAvgByRoomId(roomId, hotelId, beginTime, endTime);
		if(roomInfo==null){
			logger.error("===============没有查到该roomId的房间信息===================="+roomId);
		}
		MemberInfo memberInfo=this.memberInfoService.findMemberById(memberId);
		this.getDisCountPrice(memberInfo,roomInfo);
		/*List<RoomInfo> rooms = this.findRoomInfoAll(roomId,hotelId,"1");
		if(!rooms.isEmpty()&&rooms.size()>0) {
			RoomInfo room = rooms.get(0);
			RoomModel roomModel = this.convertToRoomModel(room, "2");
			return roomModel;
		}*/
		RoomModel roomModel = this.convertToRoomModel(roomInfo, "2",null);
		return roomModel;
	}
	
	@Override
	public List<RoomModel> RoomsAdmin(String hotelId,Date beginTime,Date endTime) {
		List<RoomModel> list = new ArrayList<RoomModel>();
		List<RoomInfo> rooms = this.findRoomInfoAll(null, hotelId, null);
		if(!rooms.isEmpty()) {
			Map<String,Object> map=new HashMap<>();
			map.put("hotelId", hotelId);
			map.put("endTime", endTime);
			map.put("beginTime", beginTime);
			List<String> roomIds = roomStatusService.findRoomIdsNotBook(map);
			for (RoomInfo roomInfo : rooms) {
				String roomId = roomInfo.getRoomId()+"";
				boolean isOk = roomIds.contains(roomId);
				if(isOk) {
					map.put("roomId", roomId);
					roomInfo.setIsBookable("0");
					List<RoomStatus> rss = this.roomStatusService.findRoomStatusAdmin(map);
					if(rss.size()>0) {
						roomInfo.setOriginalPrice(rss.get(0).getPrice());
					}
				}else {
					roomInfo = this.getRoomAvgByRoomId(roomId, hotelId, beginTime, endTime);
				}
				RoomModel roomModel = this.convertToRoomModel(roomInfo, "1",null);
				list.add(roomModel);
			}
			return list;
		}
		return null;
	}
	@Override
	@Transactional
	public void editRoomById(RoomInfo roomInfo) {
		this.updateRoomInfo(roomInfo);
		PictureInfo[] pictures = roomInfo.getPictures();
		if(pictures!=null) {
			for (PictureInfo pic : pictures) {
				pic.setAddTime(new Date());
				pic.setAddAcc(roomInfo.getModifyAcc()+"");
				pic.setTableId(roomInfo.getRoomId()+"");
				pic.setTableName("t_room_info");
				pic.setType("2");
				if(pic.getPicId()==null) {
					this.picService.save(pic);
				}else {
					this.picService.updateNotNull(pic);
				}
			}
		}
		PictureInfo picture = roomInfo.getPicture();
		if(picture!=null) {
			picture.setAddTime(new Date());
			picture.setAddAcc(roomInfo.getModifyAcc()+"");
			picture.setTableId(roomInfo.getRoomId()+"");
			picture.setTableName("t_room_info");
			picture.setType("1");
			if(picture.getPicId()==null) {
				this.picService.save(picture);
			}else {
				this.picService.updateNotNull(picture);
			}
		}
	}

	@Override//pc
	public RoomInfo getRoomInfoById(RoomInfo roomInfo) {
		List<RoomInfo> rooms=this.findRoomInfoAll(roomInfo.getRoomId()+"",roomInfo.getHotelId(),"1");
		if(!rooms.isEmpty()) {
			roomInfo=rooms.get(0);
			PictureInfo pic=new PictureInfo();
			pic.setTableName("t_room_info");
			pic.setTableId(roomInfo.getRoomId()+"");
			pic.setType("1");//查询房间列表图片
			List<PictureInfo> pics = this.picService.findPicturesPC(pic);
			if(!pics.isEmpty()) {
				roomInfo.setPicture(pics.get(0));
			}
			pic.setType("2");//查询房间列表图片
			pics = this.picService.findPicturesPC(pic);
			PictureInfo[] Pictures = new PictureInfo[pics.size()];
			pics.toArray(Pictures);
			roomInfo.setPictures(Pictures);
		}
		return roomInfo;
	}
	@Override
	public void getDisCountPrice(MemberInfo memberInfo,RoomInfo roomInfo) {
		if("1".equals(roomInfo.getIsBookable())) {
			if(memberInfo!=null) {
				MemberDiscount md = this.memberService.getMemberDiscount(memberInfo.getGrade(),roomInfo.getHotelId());
				if(md!=null) {
					 //'0  为满减   1为折扣'
					if(md.getMemberDiscountType()==0) {
						BigDecimal count=new BigDecimal(md.getMemberDiscount());
						BigDecimal mdiscount=roomInfo.getOriginalPrice().subtract(count);
						BigDecimal setScale = mdiscount.setScale(0,BigDecimal.ROUND_UP);
						roomInfo.setDiscountPrice(setScale);
					}else if(md.getMemberDiscountType()==1){
						BigDecimal count=new BigDecimal(md.getMemberDiscount());
						BigDecimal mdiscount=roomInfo.getOriginalPrice().multiply(count).multiply(new BigDecimal(0.01));
						BigDecimal setScale = mdiscount.setScale(0,BigDecimal.ROUND_UP);
						roomInfo.setDiscountPrice(setScale);
					}
					int r=roomInfo.getDiscountPrice().compareTo(BigDecimal.ZERO);
					if(r<1) {
						roomInfo.setDiscountPrice(BigDecimal.ZERO);
					}
				}else {
					roomInfo.setDiscountPrice(roomInfo.getOriginalPrice());
				}
			}else {
				String grade="1";//会员最小等级
				MemberDiscount md = this.memberService.getMemberDiscount(grade,roomInfo.getHotelId());
				if(md!=null) {
					 //'0  为满减   1为折扣'
					if(md.getMemberDiscountType()==0) {
						BigDecimal count=new BigDecimal(md.getMemberDiscount());
						BigDecimal mdiscount=roomInfo.getOriginalPrice().subtract(count);
						BigDecimal setScale = mdiscount.setScale(0,BigDecimal.ROUND_UP);
						roomInfo.setDiscountPrice(setScale);
					}else if(md.getMemberDiscountType()==1){
						BigDecimal count=new BigDecimal(md.getMemberDiscount());
						BigDecimal mdiscount=roomInfo.getOriginalPrice().multiply(count).multiply(new BigDecimal(0.01));
						BigDecimal setScale = mdiscount.setScale(0,BigDecimal.ROUND_UP);
						roomInfo.setDiscountPrice(setScale);
					}
					int r=roomInfo.getDiscountPrice().compareTo(BigDecimal.ZERO);
					if(r<1) {
						roomInfo.setDiscountPrice(BigDecimal.ZERO);
					}
				}else {
					roomInfo.setDiscountPrice(roomInfo.getOriginalPrice());
				}
			}
		}else {
			roomInfo.setDiscountPrice(roomInfo.getOriginalPrice());
		}
	}

	@Override
	public List<RoomInfo> findRoomInfoByCon(RoomInfo roomInfo) {
		try {
			Example example = new Example(RoomInfo.class);
			Criteria createCriteria = example.createCriteria();
			if (StringUtils.isNotBlank(roomInfo.getHotelId())) {
				createCriteria.andCondition("hotel_id=", roomInfo.getHotelId());
			}
			if (roomInfo.getRoomId()!=null) {
				createCriteria.andCondition("room_id=", roomInfo.getRoomId());
			}
			if (StringUtils.isNotBlank(roomInfo.getName())) {
				createCriteria.andCondition("name=",roomInfo.getName());
			}
			example.setOrderByClause("room_id");
			return this.selectByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
			return new ArrayList<>();
		}
	}
	@Override
	public String getRoomTypeById(Integer room_id) {
		return roomMapper.getRoomTypeById(room_id);
	}
	/**
	 * 查询基本房间信息
	 */
	@Override
	public RoomInfo getRoomInfoBasicById(Integer roomId) {
		return  this.mapper.selectByPrimaryKey(roomId);
	}

}
